package demoMod.invincibleOne.actions;

import com.megacrit.cardcrawl.actions.AbstractGameAction;
import com.megacrit.cardcrawl.actions.common.EmptyDeckShuffleAction;
import com.megacrit.cardcrawl.actions.utility.NewQueueCardAction;
import com.megacrit.cardcrawl.actions.utility.UnlimboAction;
import com.megacrit.cardcrawl.actions.utility.WaitAction;
import com.megacrit.cardcrawl.actions.watcher.PressEndTurnButtonAction;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.cards.CardGroup;
import com.megacrit.cardcrawl.core.AbstractCreature;
import com.megacrit.cardcrawl.core.Settings;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.monsters.AbstractMonster;
import demoMod.invincibleOne.cards.invincible.AbstractInvincibleCard;
import demoMod.invincibleOne.cards.invincible.InvincibleForm;
import demoMod.invincibleOne.powers.TauntPower;

import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;

public class AutoPlayCardAction extends AbstractGameAction {
    public static AbstractMonster getAutoPlayTarget() {
        AbstractMonster target = null;
        int minHp = Integer.MAX_VALUE;

        for (AbstractMonster monster : AbstractDungeon.getMonsters().monsters.stream().filter(m -> !m.isDeadOrEscaped() && m.hasPower(TauntPower.POWER_ID)).collect(Collectors.toList())) {
            if (monster.currentHealth < minHp) {
                minHp = monster.currentHealth;
                target = monster;
            }
        }
        if (target != null) {
            return target;
        }

        for (AbstractMonster monster : AbstractDungeon.getMonsters().monsters.stream().filter(m -> !m.isDeadOrEscaped()).collect(Collectors.toList())) {
            if (monster.currentHealth < minHp) {
                minHp = monster.currentHealth;
                target = monster;
            }
        }
        return target;
    }

    private AbstractCard getFirstPlayableCard(AbstractMonster target) {
        Optional<AbstractCard> optional = AbstractDungeon.player.hand.group.stream().filter(
                c -> c instanceof AbstractInvincibleCard && ((AbstractInvincibleCard) c).playFirst).findFirst();
        if (optional.isPresent()) {
            AbstractCard card = optional.get();
            if (card.canUse(AbstractDungeon.player, target) && card.hasEnoughEnergy()) {
                return card;
            }
        }
        for (AbstractCard card : AbstractDungeon.player.hand.group) {
            if (card.canUse(AbstractDungeon.player, target) && card.hasEnoughEnergy()) {
                return card;
            }
        }
        return null;
    }

    public AutoPlayCardAction() {
        this.duration = Settings.ACTION_DUR_FAST;
        this.actionType = ActionType.WAIT;
        this.source = AbstractDungeon.player;
    }

    @Override
    public void update() {
        // 先处理其他的action，最后打牌
        for (AbstractGameAction a: AbstractDungeon.actionManager.actions) {
            if (!(a instanceof AutoPlayCardAction)) {
                addToBot(new AutoPlayCardAction());
                isDone = true;
                return;
            }
        }

        if (this.duration == Settings.ACTION_DUR_FAST) {
            CardGroup cardGroup = AbstractDungeon.player.hand;
            target = getAutoPlayTarget();
            AbstractCard card = getFirstPlayableCard((AbstractMonster) target);
            if (target == null || card == null) {
                addToBot(new PressEndTurnButtonAction());
                isDone = true;
                return;
            }

            cardGroup.group.remove(card);
            AbstractDungeon.getCurrRoom().souls.remove(card);
            AbstractDungeon.player.limbo.group.add(card);
            card.current_y = -200.0F * Settings.scale;
            card.target_x = (float)Settings.WIDTH / 2.0F + 200.0F * Settings.xScale;
            card.target_y = (float)Settings.HEIGHT / 2.0F;
            card.targetAngle = 0.0F;
            card.lighten(false);
            card.drawScale = 0.12F;
            card.targetDrawScale = 0.75F;
            card.applyPowers();
            if (this.target == null || this.target.isDying || this.target.isDeadOrEscaped()) {
                this.addToTop(new NewQueueCardAction(card, true, false, false));
            } else {
                this.addToTop(new NewQueueCardAction(card, this.target, false, false));
            }
            this.addToTop(new UnlimboAction(card));
            if (!Settings.FAST_MODE) {
                this.addToTop(new WaitAction(Settings.ACTION_DUR_MED));
            } else {
                this.addToTop(new WaitAction(Settings.ACTION_DUR_FASTER));
            }

            this.isDone = true;
        }
    }
}
